/*
 * variable_app.c
 *
 *  Created on: Jul 20, 2020
 *      Author: liwei
 */
#include "config_app.h"

#define TAG "CONFIG_APP"

#define CFG_NAME_SPACE "VarPrt"

#define CONFIG_DEFAULT_VALUE_SERVER1_PORT 2345
#define CONFIG_DEFAULT_VALUE_SERVER2_PORT 2346
#define CONFIG_DEFAULT_VALUE_SERVER3_PORT 2347
#define CONFIG_DEFAULT_VALUE_SERIES_CODE 0x0601
#define CONFIG_DEFAULT_VALUE_VER_ID 0x0001
#define CONFIG_DEFAULT_VALUE_VERSION 0x0101

#define WIFI_STA_SSID 0x003B // 16B
#define WIFI_STA_PASSWORD 0x0043 // 16B
#define WIFI_AP_SSID 0x0055 // 16B
#define WIFI_AP_PASSWORD 0x005D // 16B
#define SERVER1_IP 0x0073 // 32B
#define SERVER2_IP 0x008A // 32B
#define SERVER3_IP 0x00A1 // 32B
#define SN_CODE 0x020F // 24B
#define PRODUCT_DESCRIPTION 0x021B // 24B
#define GATEWAY_ASSERT_CODE 0x0228 // 16B
#define DEVICE01_ASSERT_CODE 0x0230 // 16B
#define DEVICE02_ASSERT_CODE 0x0238 // 16B
#define DEVICE03_ASSERT_CODE 0x0240 // 16B
#define DEVICE04_ASSERT_CODE 0x0248 // 16B
#define DEVICE05_ASSERT_CODE 0x0250 // 16B
#define DEVICE06_ASSERT_CODE 0x0258 // 16B
#define DEVICE07_ASSERT_CODE 0x0260 // 16B
#define DEVICE08_ASSERT_CODE 0x0268 // 16B
#define DEVICE09_ASSERT_CODE 0x0270 // 16B
#define DEVICE10_ASSERT_CODE 0x0278 // 16B
#define DEVICE11_ASSERT_CODE 0x0280 // 16B
#define DEVICE12_ASSERT_CODE 0x0288 // 16B
#define DEVICE13_ASSERT_CODE 0x0290 // 16B
#define DEVICE14_ASSERT_CODE 0x0298 // 16B
#define DEVICE15_ASSERT_CODE 0x02A0 // 16B
#define DEVICE16_ASSERT_CODE 0x02A8 // 16B
#define DEVICE17_ASSERT_CODE 0x02B0 // 16B
#define DEVICE18_ASSERT_CODE 0x02B8 // 16B
#define DEVICE19_ASSERT_CODE 0x02C0 // 16B
#define DEVICE20_ASSERT_CODE 0x02C8 // 16B
#define DEVICE21_ASSERT_CODE 0x02D0 // 16B
#define DEVICE22_ASSERT_CODE 0x02D8 // 16B
#define DEVICE23_ASSERT_CODE 0x02E0 // 16B
#define DEVICE24_ASSERT_CODE 0x02E8 // 16B
#define DEVICE25_ASSERT_CODE 0x02F0 // 16B
#define DEVICE26_ASSERT_CODE 0x02F8 // 16B
#define DEVICE27_ASSERT_CODE 0x0300 // 16B
#define DEVICE28_ASSERT_CODE 0x0308 // 16B
#define DEVICE29_ASSERT_CODE 0x0310 // 16B
#define DEVICE30_ASSERT_CODE 0x0318 // 16B
#define DEVICE31_ASSERT_CODE 0x0320 // 16B
#define DEVICE32_ASSERT_CODE 0x0328 // 16B
#define PLATFORM_IP 0x0340 // 32B
#define PLATFORM_CLIENT_ID 0x0350 // 32B
#define PLATFORM_USERNAME 0x0360 // 32B
#define PLATFORM_PASSWORD 0x0370 // 32B
#define PLATFORM_LWT_TOPIC 0x0380 // 16B
#define PLATFORM_LWT_MSG 0x0388 // 16B
#define PLATFORM_SUB_TOPIC 0x0390 // 64B
#define PLATFORM_PUB_TOPIC 0x03B0 // 64B

// #define ZHONGXIN_ACCOUNT                        	0x03D0 //16B
// #define ZHONGXIN_PWD             	       	    	0x03D8 //16B
// #define ZHONGXIN_UNLOCK                             0x03E0 //16B
// #define ZHONGXIN_SWITCH								0x03E8 //16B
// #define ZHONGXIN_CHECK                              0x03F0 //16B

PartitionTableTPDF mPartitionTable = { 0 };
static nvs_handle_t mCfgNusHandle = 0;

void ConvertUint16ToString(uint16_t* source, char* dest, int number)
{
    char temp = 0;
    memcpy(dest, (char*)source, number * 2);
    for (int i = 0; i < number * 2; i++) {
        temp = dest[i];
        dest[i] = dest[i + 1];
        dest[i + 1] = temp;
        i++;
    }
}

/* transmit hex registers addr to a Decimal register addr */
char* CFG_dGet_Partition_Desc(uint16_t usIndex)
{
    static char cRet[] = "Addr\0\0\0\0";
    cRet[4] = 0x30 + ((usIndex / 1000) % 10);
    cRet[5] = 0x30 + ((usIndex / 100) % 10);
    cRet[6] = 0x30 + ((usIndex / 10) % 10);
    cRet[7] = 0x30 + (usIndex % 10);
    return (cRet);
}

static void vCfg_Device_Delete(uint16_t usDeviceIndex)
{
    uint32_t uiDeviceAddr = ((uint32_t)(&mPartitionTable.tDeviceConfig[0]) - (uint32_t)(&mPartitionTable) + (usDeviceIndex * sizeof(DeviceConfigTPDF))) >> 1;
    uint32_t uiCount = (sizeof(DeviceConfigTPDF) * (CONFIG_DEVICE_MAXSURPPORT - usDeviceIndex - 1)) >> 1;
    uint16_t i;
    if (usDeviceIndex < CONFIG_DEVICE_MAXSURPPORT - 1) {
        for (i = usDeviceIndex; i < CONFIG_DEVICE_MAXSURPPORT - 1; i++) {
            memcpy(&mPartitionTable.tDeviceConfig[i], &mPartitionTable.tDeviceConfig[i + 1], sizeof(DeviceConfigTPDF));
        }
        memset(&mPartitionTable.tDeviceConfig[CONFIG_DEVICE_MAXSURPPORT - 1], 0, sizeof(DeviceConfigTPDF));
        for (i = 0; i < uiCount; i++) {
            CFG_vSaveConfig(i + uiDeviceAddr);
        }
    }
}

uint32_t CFG_dConvertString_To_IP(char* cChar)
{
    char cIP[32];
    for (uint8_t i = 0; i < 10; i++) {
        cIP[i * 2] = cChar[i * 2 + 1];
        cIP[i * 2 + 1] = cChar[i * 2];
    }
    return (inet_addr(cIP));
}

uint32_t CFG_dConvert_To_IP(uint16_t usIpH, uint16_t usIpL)
{
    uint8_t i[4];
    i[0] = (usIpH >> 8) & 0x00ff;
    i[1] = usIpH & 0x00ff;
    i[2] = (usIpL >> 8) & 0x00ff;
    i[3] = usIpL & 0x00ff;
    return (i[0] + (i[1] << 8) + (i[2] << 16) + (i[3] << 24));
}

void CFG_dConvert_To_Uint16(uint32_t uiIP, uint16_t* usIpH, uint16_t* usIpL)
{
    uint8_t* i = (uint8_t*)&uiIP;
    *usIpH = (i[0] << 8) + (i[1]);
    *usIpL = (i[2] << 8) + (i[3]);
}

void CFG_vComm1_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tCom1Config) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(ComConfigTPDF) >> 1;
    mPartitionTable.tCom1Config.tUartConfig.usCommPort = COMM_PORT_COM1;
    mPartitionTable.tCom1Config.tUartConfig.usBaudrateH = (CONFIG_DEFAULT_VALUE_UART_BAUDRATE >> 16) & 0x0000ffff;
    mPartitionTable.tCom1Config.tUartConfig.usBaudrateL = CONFIG_DEFAULT_VALUE_UART_BAUDRATE & 0x0000ffff;
    mPartitionTable.tCom1Config.tUartConfig.usWordSize = UART_DATA_8_BITS;
    mPartitionTable.tCom1Config.tUartConfig.usParity = UART_PARITY_EVEN;
    mPartitionTable.tCom1Config.tUartConfig.usStopBits = UART_STOP_BITS_1;
    mPartitionTable.tCom1Config.usProtocolType = PROTOCOL_TYPE_MODBUS_RTU;
    mPartitionTable.tCom1Config.usJointPortType = JOINT_PORT_DOWN;
    mPartitionTable.tCom1Config.usTimeout = CONFIG_DEFAULT_VALUE_UART_TIMEOUT;
    ESP_LOGE("165", "COM1 index = %d", uiIndex);
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vComm2_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tCom2Config) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(ComConfigTPDF) >> 1;
    mPartitionTable.tCom2Config.tUartConfig.usCommPort = COMM_PORT_COM2;
    mPartitionTable.tCom2Config.tUartConfig.usBaudrateH = (CONFIG_DEFAULT_VALUE_UART_BAUDRATE >> 16) & 0x0000ffff;
    mPartitionTable.tCom2Config.tUartConfig.usBaudrateL = CONFIG_DEFAULT_VALUE_UART_BAUDRATE & 0x0000ffff;
    mPartitionTable.tCom2Config.tUartConfig.usWordSize = UART_DATA_8_BITS;
    mPartitionTable.tCom2Config.tUartConfig.usParity = UART_PARITY_EVEN;
    mPartitionTable.tCom2Config.tUartConfig.usStopBits = UART_STOP_BITS_1;
    mPartitionTable.tCom2Config.usProtocolType = PROTOCOL_TYPE_MODBUS_RTU;
    mPartitionTable.tCom2Config.usJointPortType = JOINT_PORT_DOWN;
    mPartitionTable.tCom2Config.usTimeout = CONFIG_DEFAULT_VALUE_UART_TIMEOUT;
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vCan_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tCanConfig) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(CanConfigTPDF) >> 1;
    mPartitionTable.tCanConfig.usBaudrateH = (CONFIG_DEFAULT_VALUE_CAN_BAUDRATE >> 16) & 0x0000ffff;
    mPartitionTable.tCanConfig.usBaudrateL = CONFIG_DEFAULT_VALUE_CAN_BAUDRATE & 0x0000ffff;
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vEthernet_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tEthernetConfig) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(EthernetConfigTPDF) >> 1;
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_ETHERNET_IP, &mPartitionTable.tEthernetConfig.usIPH, &mPartitionTable.tEthernetConfig.usIPL);
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_ETHERNET_GATEWAY, &mPartitionTable.tEthernetConfig.usGateWayH, &mPartitionTable.tEthernetConfig.usGateWayL);
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_ETHERNET_SUBMASK, &mPartitionTable.tEthernetConfig.usSubMaskH, &mPartitionTable.tEthernetConfig.usSubMaskL);
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_ETHERNET_DNS, &mPartitionTable.tEthernetConfig.usDNSH, &mPartitionTable.tEthernetConfig.usDNSL);
    mPartitionTable.tEthernetConfig.EthernetCliSerMode = ETHERNET_MODE_SERVER;
    mPartitionTable.tEthernetConfig.EthernetPort = CONFIG_DEFAULT_VALUE_ETHERNET_PORT;
    mPartitionTable.tEthernetConfig.EthernetTimeout = CONFIG_DEFAULT_VALUE_ETHERNET_TIMEOUT;
    mPartitionTable.tEthernetConfig.EthernetIPType = ETHERNET_IP_TYPE_STATIC;
    mPartitionTable.tEthernetConfig.EthernetDnsType = ETHERNET_DNS_TYPE_STATIC;
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vWifi_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tWifiConfig) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(WifiConfigTPDF) >> 1;
    mPartitionTable.tWifiConfig.usMode = WIFI_MODE_STA;
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_WIFI_STA_IP, &mPartitionTable.tWifiConfig.usStaIPH, &mPartitionTable.tWifiConfig.usStaIPL);
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_WIFI_STA_GATEWAY, &mPartitionTable.tWifiConfig.usStaGateWayH, &mPartitionTable.tWifiConfig.usStaGateWayL);
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_WIFI_STA_SUBMASK, &mPartitionTable.tWifiConfig.usStaSubMaskH, &mPartitionTable.tWifiConfig.usStaSubMaskL);
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_WIFI_STA_DNS, &mPartitionTable.tWifiConfig.usStaDNSH, &mPartitionTable.tWifiConfig.usStaDNSL);
    memset(mPartitionTable.tWifiConfig.cStaSSID, 0, sizeof(mPartitionTable.tWifiConfig.cStaSSID));
    memset(mPartitionTable.tWifiConfig.cStaPWD, 0, sizeof(mPartitionTable.tWifiConfig.cStaPWD));
    strcpy(mPartitionTable.tWifiConfig.cStaSSID, "daimRnNU"); // admin
    strcpy(mPartitionTable.tWifiConfig.cStaPWD, "21436587"); // 12345678
    mPartitionTable.tWifiConfig.usStaDHCPMode = WIFI_DHCP_MODE_STATIC;
    mPartitionTable.tWifiConfig.usStaDNSMode = WIFI_DNS_MODE_STATIC;
    mPartitionTable.tWifiConfig.usStaPort = CONFIG_DEFAULT_VALUE_WIFI_PORT;
    mPartitionTable.tWifiConfig.usWifiTimeout = CONFIG_DEFAULT_VALUE_WIFI_TIMEOUT;
    mPartitionTable.tWifiConfig.usSsidPwdCorrect = WIFI_SSID_PWD_WRONG;
    mPartitionTable.tWifiConfig.usSmartConfigEnable = WIFI_SC_DISENABLE;
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_WIFI_AP_IP, &mPartitionTable.tWifiConfig.usApIPH, &mPartitionTable.tWifiConfig.usApIPL);
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_WIFI_AP_SUBMASK, &mPartitionTable.tWifiConfig.usApSubMaskH, &mPartitionTable.tWifiConfig.usApSubMaskL);
    memset(mPartitionTable.tWifiConfig.cApSSID, 0, sizeof(mPartitionTable.tWifiConfig.cApSSID));
    memset(mPartitionTable.tWifiConfig.cApPWD, 0, sizeof(mPartitionTable.tWifiConfig.cApPWD));
    strcpy(mPartitionTable.tWifiConfig.cApSSID, "HCNI-TE-PS23"); // CHINT--ESP32
    strcpy(mPartitionTable.tWifiConfig.cApPWD, "21436587"); // 12345678
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_WIFI_AP_IP_POOL_START, &mPartitionTable.tWifiConfig.usApIpPoolStartH, &mPartitionTable.tWifiConfig.usApIpPoolStartL);
    CFG_dConvert_To_Uint16(CONFIG_DEFAULT_VALUE_WIFI_AP_IP_POOL_END, &mPartitionTable.tWifiConfig.usApIpPoolEndH, &mPartitionTable.tWifiConfig.usApIpPoolEndL);
    mPartitionTable.tWifiConfig.usApDHCPMode = WIFI_DHCP_MODE_STATIC;
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vIot_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tIotConfig) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(IotConfigTPDF) >> 1;
    mPartitionTable.tIotConfig.usIotType = IOT_TYPE_NONE;
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vServer1_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tServer1Config) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(ServerConfigTPDF) >> 1;
    memset(mPartitionTable.tServer1Config.cIP, 0, sizeof(mPartitionTable.tServer1Config.cIP));
    strcpy((char*)mPartitionTable.tServer1Config.cIP, ".0.0.00");
    mPartitionTable.tServer1Config.usPort = 0;
    mPartitionTable.tServer1Config.usCommType = SERVER_COMM_TYPE_ETH;
    mPartitionTable.tServer1Config.usProtocolType = SERVER_PROTOCOL_TYPE_MODBUS_RTU;
    mPartitionTable.tServer1Config.usHeartTime = CONFIG_DEFAULT_VALUE_SERVER_HEART_TIME;
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vServer2_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tServer2Config) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(ServerConfigTPDF) >> 1;
    memset(mPartitionTable.tServer1Config.cIP, 0, sizeof(mPartitionTable.tServer1Config.cIP));
    strcpy((char*)mPartitionTable.tServer2Config.cIP, ".0.0.00");
    mPartitionTable.tServer2Config.usPort = 0;
    mPartitionTable.tServer2Config.usCommType = SERVER_COMM_TYPE_ETH;
    mPartitionTable.tServer2Config.usProtocolType = SERVER_PROTOCOL_TYPE_MODBUS_RTU;
    mPartitionTable.tServer1Config.usHeartTime = CONFIG_DEFAULT_VALUE_SERVER_HEART_TIME;
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vServer3_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tServer3Config) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(ServerConfigTPDF) >> 1;
    memset(mPartitionTable.tServer1Config.cIP, 0, sizeof(mPartitionTable.tServer1Config.cIP));
    strcpy((char*)mPartitionTable.tServer3Config.cIP, ".0.0.00");
    mPartitionTable.tServer3Config.usPort = 0;
    mPartitionTable.tServer3Config.usCommType = SERVER_COMM_TYPE_ETH;
    mPartitionTable.tServer3Config.usProtocolType = SERVER_PROTOCOL_TYPE_MODBUS_RTU;
    mPartitionTable.tServer1Config.usHeartTime = CONFIG_DEFAULT_VALUE_SERVER_HEART_TIME;
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vFunction_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.usFunctionH) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = 2;
    mPartitionTable.usFunctionH = 0x0000;
    mPartitionTable.usFunctionL = 0x0141; // Default function: BLE COM1 ETH
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vDevice_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.tDeviceConfig[0]) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = (sizeof(DeviceConfigTPDF) >> 1) * CONFIG_DEVICE_MAXSURPPORT;
    memset(&mPartitionTable.tDeviceConfig[0], 0, uiSize * 2);
    if (!ucWriteflash) {
        return;
    }
    ESP_LOGE("CFG", "device clear");
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vReserve_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.ReserveConfig) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(ReserveConfigTPDF) >> 1;
    mPartitionTable.ReserveConfig.SeriesCode = CONFIG_DEFAULT_VALUE_SERIES_CODE;
    mPartitionTable.ReserveConfig.VerID = CONFIG_DEFAULT_VALUE_VER_ID;
    mPartitionTable.ReserveConfig.Version = CONFIG_DEFAULT_VALUE_VERSION;

    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vBasicInfor_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.BasicInfor) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(BasicInforTPDF) >> 1;
    mPartitionTable.BasicInfor.FactoryID = 1; // 0x01 chint   0x02 noark
    mPartitionTable.BasicInfor.ProductCategory = 7;
    mPartitionTable.BasicInfor.ProductSeries = 1;
    mPartitionTable.BasicInfor.ProductSubfamily = 1; // ESR: ETH 1 RS485
    mPartitionTable.BasicInfor.RunState = 0;
    mPartitionTable.BasicInfor.SoftwareVersion = 0x0100;
    mPartitionTable.BasicInfor.HardwareVersion = 0x0100;
    memset(mPartitionTable.BasicInfor.ProductSN, 0, sizeof(mPartitionTable.BasicInfor.ProductSN));
    memset(mPartitionTable.BasicInfor.ProductDescription, 0, sizeof(mPartitionTable.BasicInfor.ProductDescription));
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vGatewayInfor_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.GatewayInfor) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(GatewayInfoTPDF) >> 1;
    mPartitionTable.GatewayInfor.ModbusAddr = 0x00; // gateway special address
    memset(mPartitionTable.GatewayInfor.AssetCode, 0, sizeof(mPartitionTable.GatewayInfor.AssetCode));
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vDeviceAssetCode_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.DeviceAssetCode) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(DeviceAssetCodeTPDF) >> 1;
    memset(mPartitionTable.DeviceAssetCode, 0, sizeof(mPartitionTable.DeviceAssetCode));
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void CFG_vPlatform_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.PlatformConfig) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(PlatformConfigTPDF) >> 1;
    mPartitionTable.PlatformConfig.CommMode = SERVER_COMM_TYPE_ETH;
    mPartitionTable.PlatformConfig.ProtocolType = SERVER_PROTOCOL_TYPE_MQTT;
    mPartitionTable.PlatformConfig.CommPort = 1883;
    mPartitionTable.PlatformConfig.MQTTQos = 0x0000;
    mPartitionTable.PlatformConfig.TransportMode = 0x0001;
    mPartitionTable.PlatformConfig.LWTRetain = 0x0000;
    mPartitionTable.PlatformConfig.LWTQos = 0x0000;
    mPartitionTable.PlatformConfig.KeepaliveTime = 300;
    strcpy((char*)mPartitionTable.PlatformConfig.IPConfig, ".0.0.0.0");
    strcpy((char*)mPartitionTable.PlatformConfig.ClientIDConfig, "HCNIWTYA");
    strcpy((char*)mPartitionTable.PlatformConfig.UserNameConfig, "daimn");
    strcpy((char*)mPartitionTable.PlatformConfig.PasswordConfig, "daim1n134");
    memset(mPartitionTable.PlatformConfig.LWTTopicConfig, 0, sizeof(mPartitionTable.PlatformConfig.LWTTopicConfig));
    memset(mPartitionTable.PlatformConfig.LWTMessageConfig, 0, sizeof(mPartitionTable.PlatformConfig.LWTMessageConfig));
    memset(mPartitionTable.PlatformConfig.SubscribeTopicConfig, 0, sizeof(mPartitionTable.PlatformConfig.SubscribeTopicConfig));
    memset(mPartitionTable.PlatformConfig.PublishTopicConfig, 0, sizeof(mPartitionTable.PlatformConfig.PublishTopicConfig));
    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void J_CFG_ZX_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.ZhongXin) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(Zhong_Xin_AccountTPDF) >> 1;
    memset(mPartitionTable.ZhongXin.zxAccount, 0, sizeof(mPartitionTable.ZhongXin.zxAccount));
    memset(mPartitionTable.ZhongXin.zxPWD, 0, sizeof(mPartitionTable.ZhongXin.zxPWD));
    memset(mPartitionTable.ZhongXin.zxUnlock, 0, sizeof(mPartitionTable.ZhongXin.zxUnlock));
    strcpy((char*)mPartitionTable.ZhongXin.zxAccount, "daimRnNU");
    strcpy((char*)mPartitionTable.ZhongXin.zxPWD, "21436587");
    strcpy((char*)mPartitionTable.ZhongXin.zxUnlock, "068177");
    // strcpy((char *)mPartitionTable.ZhongXin.zxSwitch, "FOF");

    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        // ESP_LOGE("Account pwd unlock","uiIndex = %d",uiIndex);
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

void J_CFG_ZX_Switch_DefaultConfig(uint8_t ucWriteflash)
{
    uint32_t uiIndex = (((char*)&mPartitionTable.ZhongXin.zxSwitch) - ((char*)&mPartitionTable)) >> 1;
    uint32_t uiSize = sizeof(mPartitionTable.ZhongXin.zxSwitch) >> 1;
    strcpy((char*)mPartitionTable.ZhongXin.zxSwitch, "F");

    if (!ucWriteflash) {
        return;
    }
    while (uiSize) {
        // ESP_LOGE("Switch","uiIndex = %d",uiIndex);
        CFG_vSaveConfig(uiIndex++);
        uiSize--;
    }
}

/* set every value default configure with every hardware to use if no configure */
void CFG_vDefaultConfig(void)
{
    printf("CFGGGGGGGGGGGGGGGGGGGGGGGGGGggg\n");
    CFG_vComm1_DefaultConfig(0);
    CFG_vComm2_DefaultConfig(0);
    CFG_vCan_DefaultConfig(0);
    CFG_vEthernet_DefaultConfig(0);
    CFG_vWifi_DefaultConfig(0);
    CFG_vIot_DefaultConfig(0);
    CFG_vServer1_DefaultConfig(0);
    CFG_vServer2_DefaultConfig(0);
    CFG_vServer3_DefaultConfig(0);
    CFG_vFunction_DefaultConfig(0);
    mPartitionTable.usGatewayRunMode = 0x0001;
    CFG_vDevice_DefaultConfig(0);
    CFG_vReserve_DefaultConfig(0);
    CFG_vBasicInfor_DefaultConfig(0);
    CFG_vGatewayInfor_DefaultConfig(0);
    CFG_vDeviceAssetCode_DefaultConfig(0);
    CFG_vPlatform_DefaultConfig(0);

    J_CFG_ZX_DefaultConfig(0);
    J_CFG_ZX_Switch_DefaultConfig(0);
}

void CFG_vSaveConfig(uint16_t usIndex)
{
    esp_err_t err = ESP_FAIL;
    uint16_t* usData = ((uint16_t*)&mPartitionTable) + usIndex;
    // ESP_LOGE("578","===============================================");
    err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    // ESP_LOGE("585","===============================================");
    err = nvs_open(CFG_NAME_SPACE, NVS_READWRITE, &mCfgNusHandle);
    // ESP_LOGE("587","===============================================");
    if (err == ESP_OK) {
        err = nvs_set_u16(mCfgNusHandle, CFG_dGet_Partition_Desc(usIndex), *usData);
        if (err == ESP_OK) {
            // ESP_LOGI(TAG, "save config ok %s,usIndex = %d", CFG_dGet_Partition_Desc(usIndex),usIndex);
        } else {
            ESP_LOGE(TAG, "save config fail %s", esp_err_to_name(err));
        }
        nvs_commit(mCfgNusHandle);
    } else {
        ESP_LOGE(TAG, "Open config NVS err %s", esp_err_to_name(err));
    }
    // ESP_LOGE("605","===============================================");
    nvs_close(mCfgNusHandle);
}

void ResetConfig(void)
{
    CFG_vComm1_DefaultConfig(1);
    CFG_vComm2_DefaultConfig(1);
    CFG_vCan_DefaultConfig(1);
    CFG_vEthernet_DefaultConfig(1);
    CFG_vWifi_DefaultConfig(1);
    CFG_vIot_DefaultConfig(1);
    CFG_vServer1_DefaultConfig(1);
    CFG_vServer2_DefaultConfig(1);
    CFG_vServer3_DefaultConfig(1);
    CFG_vDevice_DefaultConfig(1);
    CFG_vPlatform_DefaultConfig(1);
}

extern uint16_t Zhong_Xin_Unlock;
extern int J_sn_store(uint8_t* sn);
extern int sn_res;
/* analysis data and save nvs flash */
void CFG_dProcess_Protocol(ModbusRtuDataTPDF* tRec, ModbusRtuDataTPDF* tSend)
{
    ESP_LOGI(TAG, "CFG_dProcess_Protocol");
    static uint8_t ucProtect = 0;
    if (ucProtect) {
        return;
    }
    // ESP_LOGE("618","===============================================");
    ucProtect = 1;
    if (tRec->ucEffect != MODBUS_RESULT_SUCCESS) {
        ucProtect = 0;
        return;
    }
    // ESP_LOGE("625","===============================================");
    tRec->ucEffect = MODBUS_RESULT_FAIL;
    tSend->ucEffect = MODBUS_RESULT_FAIL;
    tSend->tFunction = tRec->tFunction;
    tSend->ucSlaveAddr = tRec->ucSlaveAddr;
    tSend->usRegAddr = tRec->usRegAddr;
    tSend->ucEffect = MODBUS_RESULT_FAIL;
    tSend->usRegCount = tRec->usRegCount > 128 ? 128 : tRec->usRegCount;
    tSend->ucError = 0;
    switch (tRec->tFunction) {
    case ReadReg:
    case ReadInputReg:
        if (tRec->usRegCount >= 0x7F) {
            tSend->tFunction = tRec->tFunction + 0x80;
            tSend->ucError = MODBUS_ERROR_CODE_REGADDR;
            tSend->ucEffect = MODBUS_RESULT_SUCCESS;
            break;
        }
        if (tRec->usRegAddr + tRec->usRegCount <= 0x0408) {
            tSend->usDataLen = tRec->usRegCount * 2;
            // ESP_LOGE("tag","tRec->usRegAddr = %x,tRec->usRegCount = %d",tRec->usRegAddr,tRec->usRegCount);
            uint8_t* j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
            for (uint8_t i = 0; i < tRec->usRegCount; i++) {
                tSend->ucData[i * 2 + 1] = *(j++);
                tSend->ucData[i * 2] = *(j++);
            }
            tSend->ucEffect = MODBUS_RESULT_SUCCESS;
        } else if (tRec->usRegAddr >= 0x8004 && (tRec->usRegAddr + tRec->usRegCount) <= 0x8007) {
            tSend->usDataLen = tRec->usRegCount * 2;
            uint8_t* j = ((uint8_t*)&mPartitionTable.ReserveConfig.SeriesCode) + ((tRec->usRegAddr - 0x8004) * 2);
            for (uint8_t i = 0; i < tRec->usRegCount; i++) {
                tSend->ucData[i * 2 + 1] = *(j++);
                tSend->ucData[i * 2] = *(j++);
            }
            tSend->ucEffect = MODBUS_RESULT_SUCCESS;
        } else {
            tSend->tFunction = tRec->tFunction + 0x80;
            tSend->ucError = MODBUS_ERROR_CODE_REGADDR;
            tSend->ucEffect = MODBUS_RESULT_SUCCESS;
        }
        break;
    case WriteReg:
        // ESP_LOGE("676", "===============================================");
        switch (tRec->usRegAddr) {
        // Restore default configuration.
        case 0x00BA:
            switch ((tRec->ucData[0] << 8) + tRec->ucData[1]) {
            case 1:
                CFG_vComm1_DefaultConfig(1);
                break;
            case 2:
                CFG_vComm2_DefaultConfig(1);
                break;
            case 4:
                CFG_vCan_DefaultConfig(1);
                break;
            case 8:
                CFG_vEthernet_DefaultConfig(1);
                CFG_vServer1_DefaultConfig(1);
                CFG_vServer2_DefaultConfig(1);
                CFG_vServer3_DefaultConfig(1);
                break;
            case 0x10:
                CFG_vWifi_DefaultConfig(1);
                break;
            case 0x20:
                CFG_vIot_DefaultConfig(1);
                break;
            case 0x30:
                CFG_vPlatform_DefaultConfig(1);
                break;
            case 0x40:
                CFG_vDevice_DefaultConfig(1);
                break;
            case 0x3f:
                CFG_vComm1_DefaultConfig(1);
                CFG_vComm2_DefaultConfig(1);
                CFG_vCan_DefaultConfig(1);
                CFG_vEthernet_DefaultConfig(1);
                CFG_vWifi_DefaultConfig(1);
                CFG_vIot_DefaultConfig(1);
                CFG_vServer1_DefaultConfig(1);
                CFG_vServer2_DefaultConfig(1);
                CFG_vServer3_DefaultConfig(1);
                CFG_vDevice_DefaultConfig(1);
                CFG_vPlatform_DefaultConfig(1);

                // J_CFG_ZX_DefaultConfig(1);
                // J_CFG_ZX_Switch_DefaultConfig(1);
                mPartitionTable.usGatewayRunMode = 0x0001;
                break;
            }
            tSend->ucData[0] = tRec->ucData[0];
            tSend->ucData[1] = tRec->ucData[1];
            tSend->ucEffect = MODBUS_RESULT_SUCCESS;
            break;
        case 0x00BB:
            tSend->ucData[0] = tRec->ucData[0];
            tSend->ucData[1] = tRec->ucData[1];
            tSend->ucEffect = MODBUS_RESULT_SUCCESS;
            break;
        default:
            if (tRec->usRegAddr == 0x00b9) {
                uint32_t uiFunction = 0;
                uint8_t ucFucntion[2];
                ucFucntion[0] = tRec->ucData[0];
                ucFucntion[1] = tRec->ucData[1];
                uiFunction = (uint32_t)ucFucntion[0] << 8U | (uint32_t)ucFucntion[1];
                ESP_LOGW(TAG, "ui:%x  U[0]:%X, U[2]:%X", uiFunction, ucFucntion[0], ucFucntion[1]);
                // ETH  function start and Wi-Fi function start  meanwhile
                if ((uiFunction & (0x3 << 6)) >> 6 == 0x01 && (uiFunction & (0x3 << 10)) >> 10 == 0x01) {
                    ESP_LOGE(TAG, "Ethernet and Wi-Fi all START meanwhile!!!");
                    tSend->ucError = MODBUS_ERROR_CODE_DATA;
                    tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                    break;
                }
                // ETH, Wi-Fi, BLE are closed meanwhile
                else if ((uiFunction & (0x3 << 6)) >> 6 == 0x00 && (uiFunction & (0x3 << 10)) >> 10 == 0x00
                    && (uiFunction & (0x3 << 8)) >> 8 == 0x00) {
                    ESP_LOGE(TAG, "Ethernet, Wi-Fi, BLE are closed meanwhile!!!");
                    tSend->ucError = MODBUS_ERROR_CODE_DATA;
                    tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                    break;
                }
                // Wi-Fi function  AP mode don't support close BLE function
                else if ((uiFunction & (0x3 << 10)) >> 10 == 0x01) {
                    if (mPartitionTable.tWifiConfig.usMode == WIFI_MODE_AP) {
                        ESP_LOGE(TAG, "Wi-Fi function AP mode don't support close BLE function!!!");
                        tSend->ucError = MODBUS_ERROR_CODE_DATA;
                        tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                        break;
                    }
                }
            } else if (tRec->usRegAddr == 0x0032) {
                uint16_t uiValue = 0;
                uint8_t ucValue[2];
                uint32_t uiFunction;
                ucValue[0] = tRec->ucData[0];
                ucValue[1] = tRec->ucData[1];
                uiValue = (uint16_t)ucValue[0] << 8U | (uint16_t)ucValue[1];
                uiFunction = (uint32_t)mPartitionTable.usFunctionH << 16U | (uint32_t)mPartitionTable.usFunctionL;
                if (uiValue == 0x0002 && (uiFunction & (0x3 << 6)) >> 6 == 0x00 && (uiFunction & (0x3 << 8)) >> 8 == 0x00) {
                    ESP_LOGE(TAG, "Only Wi-Fi function don't set AP mode !!!");
                    tSend->ucError = MODBUS_ERROR_CODE_DATA;
                    tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                    break;
                }
            }
            if (tRec->usRegAddr < 0x00BD) {
                // ESP_LOGE("791", "=======================tRec->usRegAddr - 1 = %d ========================", tRec->usRegAddr - 1);
                tSend->usDataLen = 2;
                uint8_t* j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                *(j++) = tRec->ucData[1];
                *(j++) = tRec->ucData[0];
                CFG_vSaveConfig((tRec->usRegAddr - 1));
                tSend->ucData[0] = tRec->ucData[0];
                tSend->ucData[1] = tRec->ucData[1];
                tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                // ESP_LOGE("797","hh");
            } else if (tRec->usRegAddr < 0x01FD) {
                uint16_t i = tRec->usRegAddr - 192;
                if ((i % 10) == 0 && tRec->ucData[0] == 0 && tRec->ucData[1] == 0) {
                    i /= 10;
                    vCfg_Device_Delete(i);
                } else {
                    uint8_t* j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                    *(j++) = tRec->ucData[1];
                    *(j++) = tRec->ucData[0];
                    CFG_vSaveConfig((tRec->usRegAddr - 1));
                }
                tSend->usDataLen = 2;
                tSend->ucData[0] = tRec->ucData[0];
                tSend->ucData[1] = tRec->ucData[1];
                tSend->ucEffect = MODBUS_RESULT_SUCCESS;
            } else if (tRec->usRegAddr <= 0x03CF) {
                tSend->usDataLen = 2;
                uint8_t* j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                *(j++) = tRec->ucData[1];
                *(j++) = tRec->ucData[0];
                CFG_vSaveConfig((tRec->usRegAddr - 1));
                tSend->ucData[0] = tRec->ucData[0];
                tSend->ucData[1] = tRec->ucData[1];
                tSend->ucEffect = MODBUS_RESULT_SUCCESS;
            } else {
                tSend->tFunction = tRec->tFunction + 0x80;
                tSend->ucError = MODBUS_ERROR_CODE_REGADDR;
                tSend->ucEffect = MODBUS_RESULT_SUCCESS;
            }
            break;
        }
        break;
    case WriteMultReg:
        if (tRec->usRegAddr + tRec->usRegCount <= 0x0408) {
            uint8_t* j = NULL;
            ESP_LOGI(TAG, "tRec->usRegAddr:0x%0x", tRec->usRegAddr);
            uint32_t uiFunction = 0;
            uint8_t ucFucntion[4] = { 0 };
            switch (tRec->usRegAddr) {
            case WIFI_STA_SSID:
            case WIFI_STA_PASSWORD:
            case WIFI_AP_SSID:
            case WIFI_AP_PASSWORD:
            case GATEWAY_ASSERT_CODE:
            case DEVICE01_ASSERT_CODE:
            case DEVICE02_ASSERT_CODE:
            case DEVICE03_ASSERT_CODE:
            case DEVICE04_ASSERT_CODE:
            case DEVICE05_ASSERT_CODE:
            case DEVICE06_ASSERT_CODE:
            case DEVICE07_ASSERT_CODE:
            case DEVICE08_ASSERT_CODE:
            case DEVICE09_ASSERT_CODE:
            case DEVICE10_ASSERT_CODE:
            case DEVICE11_ASSERT_CODE:
            case DEVICE12_ASSERT_CODE:
            case DEVICE13_ASSERT_CODE:
            case DEVICE14_ASSERT_CODE:
            case DEVICE15_ASSERT_CODE:
            case DEVICE16_ASSERT_CODE:
            case DEVICE17_ASSERT_CODE:
            case DEVICE18_ASSERT_CODE:
            case DEVICE19_ASSERT_CODE:
            case DEVICE20_ASSERT_CODE:
            case DEVICE21_ASSERT_CODE:
            case DEVICE22_ASSERT_CODE:
            case DEVICE23_ASSERT_CODE:
            case DEVICE24_ASSERT_CODE:
            case DEVICE25_ASSERT_CODE:
            case DEVICE26_ASSERT_CODE:
            case DEVICE27_ASSERT_CODE:
            case DEVICE28_ASSERT_CODE:
            case DEVICE29_ASSERT_CODE:
            case DEVICE30_ASSERT_CODE:
            case DEVICE31_ASSERT_CODE:
            case DEVICE32_ASSERT_CODE:
            case PLATFORM_LWT_TOPIC:
            case PLATFORM_LWT_MSG:
            case ZHONGXIN_SWITCH:
                j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                // ESP_LOGE(TAG,"&mPartitionTable = %d,j = %d",(int)&mPartitionTable,(int)j);
                // ESP_LOGE(TAG,"cApSSID = %s,&mPartitionTable.tWifiConfig.cStaSSID = %d",mPartitionTable.tWifiConfig.cStaSSID,(int)&mPartitionTable.tWifiConfig.cStaSSID);
                // ESP_LOGE(TAG,"cStaPWD = %s,&mPartitionTable.tWifiConfig.cStaPWD = %d",mPartitionTable.tWifiConfig.cStaPWD,(int)&mPartitionTable.tWifiConfig.cStaPWD);
                // ESP_LOGE(TAG,"&mPartitionTable.ZhongXin.zxAccount = %d",(int)&mPartitionTable.ZhongXin.zxAccount);
                // ESP_LOGE(TAG,"&mPartitionTable.ZhongXin.zxPWD = %d",(int)&mPartitionTable.ZhongXin.zxPWD);
                for (uint8_t i = 0; i < 8; i++) {
                    *(j++) = 0x00;
                    *(j++) = 0x00;
                    CFG_vSaveConfig((tRec->usRegAddr - 1 + i)); // 清除NVS定义的大小区域
                }
                break;
            case ZHONGXIN_ACCOUNT:
            case ZHONGXIN_PWD:
                j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                for (uint8_t i = 0; i < ZHONGXIN_REG_COUNT; i++) {
                    *(j++) = 0x00;
                    *(j++) = 0x00;
                    CFG_vSaveConfig((tRec->usRegAddr - 1 + i)); // 清除NVS定义的大小区域
                }
                break;
            case SN_CODE:
                sn_res = J_sn_store(tRec->ucData);
                break;
            case PRODUCT_DESCRIPTION:
                j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                for (uint8_t i = 0; i < 12; i++) {
                    *(j++) = 0x00;
                    *(j++) = 0x00;
                    CFG_vSaveConfig((tRec->usRegAddr - 1 + i));
                }
                break;
            case SERVER1_IP:
            case SERVER2_IP:
            case SERVER3_IP:
            case PLATFORM_IP:
            case PLATFORM_CLIENT_ID:
            case PLATFORM_USERNAME:
            case PLATFORM_PASSWORD:
                j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                for (uint8_t i = 0; i < 16; i++) {
                    *(j++) = 0x00;
                    *(j++) = 0x00;
                    CFG_vSaveConfig((tRec->usRegAddr - 1 + i));
                }
                break;
            case PLATFORM_SUB_TOPIC:
            case PLATFORM_PUB_TOPIC:
                j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                for (uint8_t i = 0; i < 32; i++) {
                    *(j++) = 0x00;
                    *(j++) = 0x00;
                    CFG_vSaveConfig((tRec->usRegAddr - 1 + i));
                }
                break;

            default:
                break;
            }
            // gateway configuration hardware state word. Default wi-fi
            if (tRec->usRegAddr == 0x00b8) {
                for (uint8_t i = 0; i < tRec->usRegCount; i++) {
                    ucFucntion[i * 2] = tRec->ucData[i * 2];
                    ucFucntion[i * 2 + 1] = tRec->ucData[i * 2 + 1];
                }
                uiFunction = (uint32_t)ucFucntion[0] << 24U | (uint32_t)ucFucntion[1] << 16U | (uint32_t)ucFucntion[2] << 8U | (uint32_t)ucFucntion[3];
                // ETH  function start and Wi-Fi function start  meanwhile
                if ((uiFunction & (0x3 << 6)) >> 6 == 0x01 && (uiFunction & (0x3 << 10)) >> 10 == 0x01) {
                    ESP_LOGE(TAG, "Ethernet and Wi-Fi all START meanwhile!!!");
                    tSend->ucError = MODBUS_ERROR_CODE_DATA;
                    tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                    break;
                }
                // ETH, Wi-Fi, BLE are closed meanwhile
                else if ((uiFunction & (0x3 << 6)) >> 6 == 0x00 && (uiFunction & (0x3 << 10)) >> 10 == 0x00
                    && (uiFunction & (0x3 << 10)) >> 10 == 0x00) {
                    ESP_LOGE(TAG, "Ethernet, Wi-Fi, BLE are closed meanwhile!!!");
                    tSend->ucError = MODBUS_ERROR_CODE_DATA;
                    tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                    break;
                }
                // Wi-Fi function  AP mode don't support close BLE function
                else if ((uiFunction & (0x3 << 10)) >> 10 == 0x01) {
                    if (mPartitionTable.tWifiConfig.usMode == WIFI_MODE_AP) {
                        ESP_LOGE(TAG, "Wi-Fi function AP mode don't support close BLE function!!!");
                        tSend->ucError = MODBUS_ERROR_CODE_DATA;
                        tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                        break;
                    }
                }
            } else if (tRec->usRegAddr == 0x00b9) {
                for (uint8_t i = 0; i < tRec->usRegCount; i++) {
                    ucFucntion[i * 2] = tRec->ucData[i * 2];
                    ucFucntion[i * 2 + 1] = tRec->ucData[i * 2 + 1];
                }
                uiFunction = (uint32_t)ucFucntion[0] << 8U | (uint32_t)ucFucntion[1];
                ESP_LOGW(TAG, "ui:%x  U[0]:%X, U[2]:%X", uiFunction, ucFucntion[0], ucFucntion[1]);
                // ETH  function start and Wi-Fi function start  meanwhile
                if ((uiFunction & (0x3 << 6)) >> 6 == 0x01 && (uiFunction & (0x3 << 10)) >> 10 == 0x01) {
                    ESP_LOGE(TAG, "Ethernet and Wi-Fi all START meanwhile!!!");
                    tSend->ucError = MODBUS_ERROR_CODE_DATA;
                    tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                    break;
                }
                // ETH, Wi-Fi, BLE are closed meanwhile
                else if ((uiFunction & (0x3 << 6)) >> 6 == 0x00 && (uiFunction & (0x3 << 10)) >> 10 == 0x00
                    && (uiFunction & (0x3 << 8)) >> 8 == 0x00) {
                    ESP_LOGE(TAG, "Ethernet, Wi-Fi, BLE are closed meanwhile!!!");
                    tSend->ucError = MODBUS_ERROR_CODE_DATA;
                    tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                    break;
                }
                // Wi-Fi function  AP mode don't support close BLE function
                else if ((uiFunction & (0x3 << 10)) >> 10 == 0x01) {
                    if (mPartitionTable.tWifiConfig.usMode == WIFI_MODE_AP) {
                        ESP_LOGE(TAG, "Wi-Fi function AP mode don't support close BLE function!!!");
                        tSend->ucError = MODBUS_ERROR_CODE_DATA;
                        tSend->ucEffect = MODBUS_RESULT_SUCCESS;
                        break;
                    }
                }
            }
            // normal  storage flash
            if ((tRec->usRegAddr != SN_CODE && tRec->usRegAddr != 0x020E) || sn_res == 0x0A) // SN、HW分区表地址跳过，只有efuse写SN返回A时刷新分区表。
            {
                if (sn_res == 0x0A) {
                    sn_res = 0;
                    ESP_LOGE("SN to MP", "sn_res = %x", sn_res);
                }
                j = ((uint8_t*)&mPartitionTable) + ((tRec->usRegAddr - 1) * 2);
                ESP_LOGE("TAG", "tRec->usRegCount = %d", tRec->usRegCount);
                for (uint8_t i = 0; i < tRec->usRegCount; i++) {
                    *(j++) = tRec->ucData[i * 2 + 1];
                    *(j++) = tRec->ucData[i * 2];
                    ESP_LOGE("TAG", "tRec->usRegAddr - 1 + i = %d", tRec->usRegAddr - 1 + i);
                    CFG_vSaveConfig((tRec->usRegAddr - 1 + i)); // 写入接收寄存器数量的值
                }
            }

            tSend->ucEffect = MODBUS_RESULT_SUCCESS;
        } else {
            tSend->tFunction = tRec->tFunction + 0x80;
            tSend->ucError = MODBUS_ERROR_CODE_REGADDR;
            tSend->ucEffect = MODBUS_RESULT_SUCCESS;
        }
        break;
    case ReportSlaveID:
        tSend->usDataLen = 9 + 12 * 2 + 12 * 2;
        tSend->ucData[0] = mPartitionTable.BasicInfor.FactoryID & 0x00ff;
        tSend->ucData[1] = mPartitionTable.BasicInfor.ProductCategory & 0x00ff;
        tSend->ucData[2] = mPartitionTable.BasicInfor.ProductSeries & 0x00ff;
        tSend->ucData[3] = mPartitionTable.BasicInfor.ProductSubfamily & 0x00ff;
        tSend->ucData[4] = mPartitionTable.BasicInfor.RunState & 0x00ff;
        tSend->ucData[5] = (mPartitionTable.BasicInfor.SoftwareVersion >> 8) & 0x00ff;
        tSend->ucData[6] = mPartitionTable.BasicInfor.SoftwareVersion & 0x00ff;
        tSend->ucData[7] = (mPartitionTable.BasicInfor.HardwareVersion >> 8) & 0x00ff;
        tSend->ucData[8] = mPartitionTable.BasicInfor.HardwareVersion & 0x00ff;
        for (int i = 0; i < 12; i++) {
            tSend->ucData[9 + 2 * i] = (mPartitionTable.BasicInfor.ProductSN[i] >> 8) & 0x00ff;
            tSend->ucData[9 + 2 * i + 1] = mPartitionTable.BasicInfor.ProductSN[i] & 0x00ff;
        }
        for (int i = 0; i < 12; i++) {
            tSend->ucData[33 + 2 * i] = (mPartitionTable.BasicInfor.ProductDescription[i] >> 8) & 0x00ff;
            tSend->ucData[33 + 2 * i + 1] = mPartitionTable.BasicInfor.ProductDescription[i] & 0x00ff;
        }
        tSend->ucEffect = MODBUS_RESULT_SUCCESS;
        break;
    default:
        tSend->tFunction = tRec->tFunction + 0x80;
        tSend->ucError = MODBUS_ERROR_CODE_FUNCTION;
        tSend->ucEffect = MODBUS_RESULT_SUCCESS;
        break;
    }
    ucProtect = 0;
}

void CFG_vInit(void)
{
    esp_err_t tRet;
    uint16_t usLen = sizeof(mPartitionTable) >> 1;
    uint16_t* usData = (uint16_t*)&mPartitionTable;
    tRet = nvs_flash_init();
    if (tRet == ESP_ERR_NVS_NO_FREE_PAGES || tRet == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ESP_LOGE("tag", "erase nvs");
        tRet = nvs_flash_init();
    }
    tRet = nvs_open(CFG_NAME_SPACE, NVS_READWRITE, &mCfgNusHandle);
    if (tRet == ESP_OK) {
        ESP_LOGI(TAG, "open Done");
        /* get every value for given key in partition table */
        for (uint16_t i = 0; i < usLen; i++) {
            tRet = nvs_get_u16(mCfgNusHandle, CFG_dGet_Partition_Desc(i), usData);
            if (i == 999) {
                ESP_LOGE("TAG", "999 = %x", *usData);
            }
            usData++;
            if (tRet != ESP_OK) {
                ESP_LOGE(TAG, "read fail %d", i);
                break;
            }
        }
        if (tRet == ESP_OK) {
            nvs_close(mCfgNusHandle);
            /* copy device info to mDevice structures from partition table */
            ESP_LOGE("1100", "read MP OK");
            for (uint8_t i = 0; i < CONFIG_DEVICE_MAXSURPPORT; i++) {
                memcpy(&mDevice[i].tDeviceConfig, &mPartitionTable.tDeviceConfig[i], sizeof(DeviceConfigTPDF));
            }
            return;
        }
    } else {
        ESP_LOGE(TAG, "Error (%s) opening NVS handle!", esp_err_to_name(tRet));
    }
    CFG_vDefaultConfig();
    for (uint8_t i = 0; i < CONFIG_DEVICE_MAXSURPPORT; i++) {
        memset(&mDevice[i].tDeviceConfig, 0, sizeof(DeviceConfigTPDF));
    }
    usData = (uint16_t*)&mPartitionTable;
    /* set configure to nvs flash */
    for (uint16_t i = 0; i < usLen; i++) {
        tRet = nvs_set_u16(mCfgNusHandle, CFG_dGet_Partition_Desc(i), *usData);
        usData++;
        if (tRet != ESP_OK) {
            ESP_LOGE(TAG, "write fail %s", esp_err_to_name(tRet));
            nvs_flash_erase();
            return;
        }
    }
    int n = nvs_commit(mCfgNusHandle);
    ESP_LOGE("TAG", "nvs_commit res = %d ", n);
    nvs_close(mCfgNusHandle);
}
